<template>
  <!-- 导入对话框 -->
  <el-dialog :title="title" :visible.sync="open" width="400px" append-to-body>
    <el-upload
      ref="upload"
      :limit="1"
      accept=".xlsx, .xls"
      :headers="headers"
      :action="actionUrl"
      :disabled="isUploading"
      :on-progress="handleFileUploadProgress"
      :on-success="handleFileSuccess"
      :on-error="handleFileError"
      :before-upload="beforeUpload"
      :auto-upload="false"
      drag
    >
      <i class="el-icon-upload"></i>
      <div class="el-upload__text">将文件拖到此处，或<em>点击上传</em></div>
      <div class="el-upload__tip text-center" slot="tip">
        <span>仅允许导入xls、xlsx格式文件。</span>
        <el-link type="primary" :underline="false" style="font-size:12px;vertical-align: baseline;" @click="downloadTemplate">下载模板</el-link>
      </div>
    </el-upload>
    <div slot="footer" class="dialog-footer">
      <el-button type="primary" @click="submitUpload" :loading="isUploading">确 定</el-button>
      <el-button @click="cancel">取 消</el-button>
    </div>
  </el-dialog>
</template>

<script>
export default {
  name: "ExcelImport",
  props: {
    // 对话框标题
    title: {
      type: String,
      default: "数据导入"
    },
    // 导入API地址
    importUrl: {
      type: String,
      required: true
    },
    // 下载模板API地址
    templateUrl: {
      type: String,
      required: true
    },
    // 模板文件名
    templateFileName: {
      type: String,
      default: "导入模板.xlsx"
    },
    // 是否显示对话框
    visible: {
      type: Boolean,
      default: false
    },
    // 是否支持更新已存在数据
    updateSupport: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      // 是否正在上传
      isUploading: false,
      // 请求头
      headers: {
        Authorization: "Bearer " + this.$store.getters.token
      }
    }
  },
  computed: {
    // 对话框显示状态
    open: {
      get() {
        return this.visible
      },
      set(value) {
        this.$emit('update:visible', value)
      }
    },
    // 完整的导入API地址
    actionUrl() {
      const baseUrl = process.env.VUE_APP_BASE_API
      return `${baseUrl}${this.importUrl}?updateSupport=${this.updateSupport}`
    }
  },
  methods: {
    /**
     * 下载导入模板
     */
    downloadTemplate() {
      this.$emit('download-template', {
        templateUrl: this.templateUrl,
        fileName: this.templateFileName
      })
    },

    /**
     * 文件上传前的验证
     */
    beforeUpload(file) {
      const isExcel = file.type === 'application/vnd.ms-excel' ||
        file.type === 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
      const isLt10M = file.size / 1024 / 1024 < 10

      if (!isExcel) {
        this.$modal.msgError('上传文件只能是 xls、xlsx 格式!')
        return false
      }
      if (!isLt10M) {
        this.$modal.msgError('上传文件大小不能超过 10MB!')
        return false
      }

      this.$emit('before-upload', file)
      return true
    },

    /**
     * 文件上传中处理
     */
    handleFileUploadProgress(event, file, fileList) {
      this.isUploading = true
      this.$emit('upload-progress', {
        event,
        file,
        fileList,
        progress: event.percent
      })
    },

    /**
     * 文件上传成功处理
     */
    handleFileSuccess(response, file, fileList) {
      this.isUploading = false
      this.$refs.upload.clearFiles()

      if (response.code === 200) {
        this.$emit('upload-success', {
          response,
          file,
          fileList,
          message: response.msg
        })
        this.open = false
      } else {
        this.handleFileError(new Error(response.msg), file, fileList)
      }
    },

    /**
     * 文件上传失败处理
     */
    handleFileError(error, file, fileList) {
      this.isUploading = false
      this.$emit('upload-error', {
        error,
        file,
        fileList,
        message: error.message || '上传失败'
      })
    },

    /**
     * 提交上传文件
     */
    submitUpload() {
      if (this.$refs.upload.uploadFiles.length === 0) {
        this.$modal.msgWarning('请选择要上传的文件')
        return
      }
      this.$refs.upload.submit()
    },

    /**
     * 取消导入
     */
    cancel() {
      this.$refs.upload.clearFiles()
      this.isUploading = false
      this.open = false
      this.$emit('cancel')
    },

    /**
     * 清空已选文件
     */
    clearFiles() {
      this.$refs.upload.clearFiles()
    }
  }
}
</script>

<style scoped>
.el-upload__tip {
  line-height: 1.5;
}
.text-center {
  text-align: center;
}
</style>
